//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <engine.h>

Boolean ClipLine(
    /* [in] */ Region * line,
    /* [in] */ Region * clip)
{
    UInt8 regionCode1 = REGION_CODE(line->left, line->top,
                        clip->left, clip->right, clip->top, clip->bottom);

    UInt8 regionCode2 = REGION_CODE(line->right, line->bottom,
                        clip->left, clip->right, clip->top, clip->bottom);

    while (regionCode1 | regionCode2) {
        // line completely outside the clipping rectangle
        //
        if (regionCode1 & regionCode2) {
            return FALSE;
        }

        if (regionCode1) {
            // divide line at bottom
            //
            if (regionCode1 & 8) {
                line->left = line->left + (line->right - line->left)
                                    * (clip->bottom - line->top)
                                    / (line->bottom - line->top);
                line->top = clip->bottom;
            }
            // divide line at top
            //
            else if (regionCode1 & 4) {
                line->left = line->left + (line->right - line->left)
                                    * (clip->top - line->top)
                                    / (line->bottom - line->top);
                line->top = clip->top;
            }
            // divide line at right
            //
            else if (regionCode1 & 2) {
                line->top = line->top + (line->bottom - line->top)
                                    * (clip->right - line->left)
                                    / (line->right - line->left);
                line->left = clip->right;
            }
            // divide line at right
            //
            else if (regionCode1 & 1) {
                line->top = line->top + (line->bottom - line->top)
                                    * (clip->left - line->left)
                                    / (line->right - line->left);
                line->left = clip->left;
            }

            regionCode1 = REGION_CODE(line->left, line->top,
                            clip->left, clip->right, clip->top, clip->bottom);
        }
        else {
            // divide line at bottom
            //
            if (regionCode2 & 8) {
                line->right = line->left + (line->right - line->left)
                                    * (clip->bottom - line->top)
                                    / (line->bottom - line->top);
                line->bottom = clip->bottom;
            }
            // divide line at top
            //
            else if (regionCode2 & 4) {
                line->right = line->left + (line->right - line->left)
                                    * (clip->top - line->top)
                                    / (line->bottom - line->top);
                line->bottom = clip->top;
            }
            // divide line at right
            //
            else if (regionCode2 & 2) {
                line->bottom = line->top + (line->bottom - line->top)
                                    * (clip->right - line->left)
                                    / (line->right - line->left);
                line->right = clip->right;
            }
            // divide line at right
            //
            else if (regionCode2 & 1) {
                line->bottom = line->top + (line->bottom - line->top)
                                    * (clip->left - line->left)
                                    / (line->right - line->left);
                line->right = clip->left;
            }

            regionCode2 = REGION_CODE(line->right, line->bottom,
                            clip->left, clip->right, clip->top, clip->bottom);
        }
    }

    // successfully clipped or clipping not neccessary
    //
    return TRUE;
}
